<template>
  <el-card class="panel-card">
    <el-form class="filter-form" label-position="top" :model="fromData">
      <el-tabs v-model="activeName">
        <el-tab-pane label="基本设置" name="baseSetting">
          <el-form-item :label="$t('others.visual.Table')">
            <el-select v-model="filterPayload.tableName" clearable placeholder="数据表" @change="SelectFieldName">
              <el-option v-for="(item,index) in fromData.table" :key="index" :label="item.alias" :value="item.column" />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('others.visual.IntervalField')">
            <el-select
              v-model="filterPayload.intervalField"
              filterable
              allow-create
              default-first-option
              placeholder="区间字段"
              @change="onSubmit"
            >
              <el-option
                v-for="(item,index) in fromData.filters.fields"
                :key="index"
                :label="item.alias"
                :value="item.column"
              />
            </el-select>
            <el-radio-group v-if="filterPayload.intervalIsDatetime" v-model="filterPayload.intervalFieldDataFormat">
              <el-radio label="%Y-%m-%d">按日</el-radio>
              <el-radio label="%Y-%m">按月</el-radio>
              <el-radio label="%Y">按年</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="区间字段类型">
            <el-switch v-model="filterPayload.intervalIsDatetime" active-text="时间格式" inactive-text="非时间" />
          </el-form-item>
          <el-form-item :label="$t('others.visual.ValueField')" style="border: 1px #3A71A8 solid;padding: 10px;border-radius: 10px">
            <el-tooltip effect="dark" :content="$t('others.visual.ValueFieldTips')" placement="bottom">
              <el-select
                v-model="filterPayload.valueField.field"
                filterable
                allow-create
                default-first-option
                placeholder="值字段"
                @change="onSubmit"
              >
                <el-option
                  v-for="(item,index) in fromData.filters.fields"
                  :key="index"
                  :label="item.alias"
                  :value="item.column"
                />
              </el-select>
            </el-tooltip>
            多维运算
            <el-row :gutter="20">
              <el-col :span="12">
                <el-select
                  v-model="filterPayload.valueField.symbol"
                  filterable
                  allow-create
                  clearable
                  default-first-option
                  placeholder="符号"
                  @change="onSubmit"
                >
                  <el-option
                    v-for="(item) in fromData.valueField.symbol"
                    :key="item"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </el-col>
              <el-col :span="12">
                <el-select
                  v-model="filterPayload.valueField.toField"
                  filterable
                  allow-create
                  clearable
                  default-first-option
                  placeholder="运算字段"
                  @change="onSubmit"
                >
                  <el-option
                    v-for="(item,index) in fromData.filters.fields"
                    :key="index"
                    :label="item.alias"
                    :value="item.column"
                  />
                </el-select>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item :label="$t('others.visual.ShowField')">
            <el-select
              v-model="filterPayload.showField"
              filterable
              allow-create
              default-first-option
              placeholder="显示字段"
              @change="onSubmit"
            >
              <el-option
                v-for="(item,index) in fromData.filters.fields"
                :key="index"
                :label="item.alias"
                :value="item.column"
              />
            </el-select>
          </el-form-item>
          <!--          <el-form-item :label="$t('others.visual.SortField')">
            <el-select
              v-model="filterPayload.sortField"
              filterable
              allow-create
              default-first-option
              placeholder="排序字段"
              @change="onSubmit"
            >
              <el-option
                v-for="(item,index) in fromData.filters.fields"
                :key="index"
                :label="item.alias"
                :value="item.column"
              />
            </el-select>
          </el-form-item>-->
          <el-form-item :label="$t('others.visual.SortBy')">
            <el-select v-model="filterPayload.sortBy" allow-create clearable placeholder="排序模式" @change="onSubmit">
              <el-option v-for="(item,index) in fromData.sortBy" :key="index" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-tab-pane>
        <el-tab-pane label="图形配置" name="visualProperties">
          <el-form-item :label="$t('others.visual.GraphicsModel')">
            <el-select v-model="filterPayload.graphicsModel" allow-create clearable placeholder="请选择">
              <el-option
                v-for="(item,index) in fromData.graphicsModel"
                :key="index"
                :label="item.label"
                :value="item.value"
              >
                {{ item.label }}
                <svg-icon :icon-class="item.icon" />
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="filterPayload.graphicsModel !=='pivot'" label="模式">
            <el-select v-model="filterPayload.trigger" clearable placeholder="请选择">
              <el-option v-for="(item,index) in fromData.trigger" :key="index" :label="item.label" :value="item.value">
                {{ item.label }}
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="filterPayload.graphicsModel ==='bar'" label="是否显示label">
            <el-switch v-model="filterPayload.barShowLabel" active-text="显示" inactive-text="不显示" />
          </el-form-item>
          <el-form-item :label="$t('others.visual.ShowMode')">
            <el-select v-model="filterPayload.showMode" clearable placeholder="请选择">
              <el-option
                v-for="(item,index) in fromData.showMode"
                :key="index"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-tab-pane>
        <el-tab-pane label="筛选" name="third">
          <el-form-item label="筛选字段">
            <el-select
              v-model="fromData.filters.ret.field"
              clearable
              class="input-with-select"
              filterable
              placeholder="筛选字段"
            >
              <el-option
                v-for="(fieldItem,i) in fromData.filters.fields"
                :key="i"
                class="item"
                :label="fieldItem.alias"
                :value="fieldItem.column"
              />
            </el-select>
          </el-form-item>
          <el-form-item class="condition" label="筛选条件">
            <el-input v-model="fromData.filters.ret.value" placeholder="过滤值" />
          </el-form-item>
          <el-form-item label="过滤条件">
            <el-select
              v-model="fromData.filters.ret.symbol"
              clearable
              class="input-with-select"
              filterable
              placeholder="过滤条件"
            >
              <el-option
                v-for="(symbolItem,ind) in fromData.filters.symbol"
                :key="ind"
                :label="symbolItem"
                :value="symbolItem"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="已选条件">
            <el-row :gutter="10">
              <el-col v-for="(filterItem, index) in filterPayload.filters" :key="index" :span="12">
                <el-tag closable @close="delTag(index)">
                  <span class="padd-left">{{ filterItem.field }}</span>
                  <span class="padd-left">{{ filterItem.symbol }}</span>
                  <span class="padd-left">{{ filterItem.value }}</span>
                </el-tag>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item>
            <el-button @click="addFilter">添加</el-button>
          </el-form-item>
          <el-form-item label="显示数据量">
            <el-input-number v-model="filterPayload.listQuery.total" :min="20" label="数据量" @change="handleCurrentChange" />
          </el-form-item>
          <el-form-item label="显示页码">
            <el-input-number v-model="filterPayload.listQuery.pageSize" :min="1" label="页码" @change="handleSizeChange" />
          </el-form-item>
          <!--          <el-pagination
            :page-sizes="[20,30,50,100,150,200,1000000]"
            class="page-help"
            :page-size="filterPayload.listQuery.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="filterPayload.listQuery.total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />-->
        </el-tab-pane>
        <el-tab-pane label="更多操作" name="otherOpera">
          <el-form-item :label="$t('others.visual.PreviewSql')">
            <el-input
              v-model="preview.sql"
              style="background-color: white"
              type="textarea"
              disabled
              :autosize="{ minRows: 6, maxRows: 6}"
              :placeholder="$t('others.visual.PreviewSql')"
            />
          </el-form-item>
          <el-form-item :label="$t('others.visual.Save')">
            <el-button type="primary" plain @click="dialogVisible = true">
              Save <i class="el-icon-right" />
            </el-button>
          </el-form-item>
          <el-form-item label="可用模板">
            <el-row :gutter="20">
              <el-col
                v-for="temp in visualTemplate"
                :key="temp.id"
                :span="6"
              >
                <el-popover
                  placement="top-start"
                  width="100"
                  trigger="hover"
                  :content="temp.message"
                >
                  <el-tag
                    slot="reference"
                    :alt="temp.message"
                    closable
                    type="success"
                    effect="dark"
                    :disable-transitions="false"
                    @close="deleteTemplate(temp.id)"
                  >
                    <span @click="usingTemplate(temp)">{{ temp.name }}</span>
                  </el-tag>
                </el-popover>
              </el-col>
            </el-row>
            <!--            <el-button
              v-for="temp in visualTemplate"
              :key="temp.id"
              type="success"
              size="mini"
              @click="usingTemplate(temp)"
            >
              <i class="el-icon-delete" style="color: red" @click="deleteTemplate(temp.id)" />
              {{ temp.name }}
            </el-button>-->
          </el-form-item>
          <el-form-item label="自定义脚本">
            <el-button type="primary" @click="drawer = true">
              自定义脚本 <i class="el-icon-right" />
            </el-button>
          </el-form-item>
        </el-tab-pane>
      </el-tabs>
      <!--      运行按钮-->
      <el-form-item>
        <el-button type="primary" style="width: 100%" @click="onSubmit">Run <i class="el-icon-right" /></el-button>
      </el-form-item>
    </el-form>
    <!--    模板弹窗-->
    <el-dialog width="30%" title="保存模板" :visible.sync="dialogVisible">
      <el-form :ref="filterPayload" :rules="rules">
        <el-form-item label="模板名称(推荐5个字以内)" prop="templateName">
          <el-input v-model="filterPayload.templateName" />
        </el-form-item>
        <el-form-item label="模板描述" prop="templateMessage">
          <el-input v-model="filterPayload.templateMessage" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveTemplate">确 定</el-button>
      </div>
    </el-dialog>
    <!--    自定义脚本抽屉-->
    <el-drawer
      size="80%"
      :visible.sync="drawer"
      :before-close="drawerClose"
    >
      <span slot="title">自定义脚本
        <el-tooltip class="item" effect="dark" content="执行自定义的代码" placement="right">
          <svg-icon icon-class="ask" />
        </el-tooltip>
      </span>
      <el-form class="filter-form" label-position="top" :model="fromData" style="overflow:auto;height: 852px">
        <el-form-item>
          <span slot="label">自定义sql脚本
            <el-tooltip placement="right" effect="light" content="返回pandas的DataFrame对象">
              <svg-icon icon-class="ask" />
            </el-tooltip>
          </span>
          <code-editor
            ref="_firstRefs"
            v-model="customizeScript.sql"
            class="editor h-100"
            language="sql"
          />
        </el-form-item>
        <el-form-item>
          <span slot="label">自定义python处理脚本,可使用的包：
            <el-tooltip placement="right" effect="light">
              <div slot="content">
                <el-card style="height: 400px;overflow: auto">
                  <i class="el-icon-document-copy" style="color: red;font-size: 20px" @click="copyPackagesName" />
                  <textarea id="package-content" type="text" style="display: none" />
                  <div>
                    <div v-for="sp in serverPackages" :key="sp">
                      {{ sp }}
                    </div>
                  </div>
                </el-card>
              </div>
              <svg-icon icon-class="package" style="font-size: 20px" />
            </el-tooltip>
          </span>
          <code-editor
            ref="_firstRefs"
            v-model="customizeScript.py"
            class="editor h-100"
            language="python"
          />
        </el-form-item>
        <el-form-item label="自定义javaScript脚本(不写将使用默认)">
          <code-editor
            ref="_firstRefs"
            v-model="customizeScript.js"
            class="editor h-100"
            language="javascript"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="SaveScriptTemplate">Save </el-button>
          <el-button type="success" @click="RunScriptTemplate">Run <i class="el-icon-right" /></el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
  </el-card>
</template>

<script>
import {
  deleteVisualTemplate,
  getBrand, getServerPackages,
  getVisualTemplate, runCustomizeScript
} from '@/api/visualFilter'
import CodeEditor from '@/components/CodeEditor'
import {
  fieldAlias
  // tableAlias
} from '@/api/remote-search.js'
export default {
  name: 'Panel',
  components: {
    CodeEditor
  },
  props: {
    filterPayload: {
      type: Object,
      default: () => {
        return {}
      }
    },
    preview: {
      type: Object,
      default: () => {
        return {
          sql: ''
        }
      }
    }
  },
  data() {
    return {
      customizeScript: {
        sql: '',
        py:
          'def task_run(request,df:DataFrame) -> rest_framework.response.Response:\n' +
          '    """示例代码|默认代码\n' +
          '    {\n' +
          '      "filters":[\n' +
          '          {\n' +
          '              "field":"money",\n' +
          '              "symbol":">",\n' +
          '              "value":"400"\n' +
          '          }\n' +
          '      ],\n' +
          '      "listQuery":{\n' +
          '          "pageSize":20,\n' +
          '          "page":2,\n' +
          '          "total":0\n' +
          '      },\n' +
          '      "tableName":"shop_info",\n' +
          '      "graphicsModel":"line",\n' +
          '      "showMode":"newVisual",\n' +
          '      "valueField":"sales",\n' +
          '      "intervalField":"update_time",\n' +
          '      "showField":"title",\n' +
          '      "sortBy":"asc",\n' +
          '      "sortField":"sales",\n' +
          '      "preview":false\n' +
          '    }\n' +
          '    """\n' +
          '    data = request.data\n' +
          '    # 表名\n' +
          '    tableName = data.get("tableName")\n' +
          '    # 图形的展示方式\n' +
          '    graphicsModel = data.get("graphicsModel")\n' +
          '    # 显示的方式 追加和新图形\n' +
          '    showMode = data.get("showMode")\n' +
          '    # 值的字段\n' +
          '    valueField = data.get("valueField")\n' +
          '    # 区间字段\n' +
          '    intervalField = data.get("intervalField")\n' +
          '    # 区间字段是否为时间格式 bool类型\n' +
          '    intervalIsDatetime = data.get("intervalIsDatetime")\n' +
          '    # 显示的标题字段\n' +
          '    showField = data.get("showField")\n' +
          '    # 排序\n' +
          '    sortField = data.get("sortField")\n' +
          '    # 排序方式 asc和desc\n' +
          '    sortBy = data.get("sortBy")\n' +
          '    # 筛选\n' +
          '    filters_where = data.get("filters")\n' +
          '    # 图形的显示方式 item axis\n' +
          '    trigger = data.get("trigger")\n' +
          '    # 柱状图是否显示label\n' +
          '    barShowLabel = data.get("barShowLabel")\n' +
          '    # 分页\n' +
          '    listQuery = data["listQuery"]\n' +
          '    pageSize = int(listQuery.get("pageSize"))\n' +
          '    page = int(listQuery.get("page")) - 1\n' +
          '    fromData = {\n' +
          '      "filters": filters_where,\n' +
          '      "listQuery": {\n' +
          '          "pageSize": pageSize,\n' +
          '          "page": int(page) + 1,\n' +
          '          "total": total_df.to_dict("records")[0]["total"]\n' +
          '      },\n' +
          '      "tableName": tableName,\n' +
          '      "graphicsModel": graphicsModel,\n' +
          '      "showMode": showMode,\n' +
          '      "valueField": valueField,\n' +
          '      "intervalField": intervalField,\n' +
          '      "showField": showField,\n' +
          '      "sortBy": sortBy,\n' +
          '      "sortField": sortField,\n' +
          '      "trigger": trigger,\n' +
          '      "intervalIsDatetime": intervalIsDatetime,\n' +
          '      "barShowLabel": barShowLabel\n' +
          '    }\n' +
          '    show_field_column_alias, value_field_column_alias, interval_field_column_alias = [rand_name(6) for _ in range(3)]\n' +
          '    opera = visual_opera[graphicsModel](dataframe=df,\n' +
          '                                        from_data=fromData,\n' +
          '                                        show_field_column_alias=show_field_column_alias,\n' +
          '                                        value_field_column_alias=value_field_column_alias,\n' +
          '                                        interval_field_column_alias=interval_field_column_alias)\n' +
          '    try:\n' +
          '        ret = opera.do()\n' +
          '    except Exception as do_err:\n' +
          '        return Result.error(message=str(do_err))\n' +
          '    return Result.success(data={\n' +
          '        \'fromData\': fromData, # 前端请求参数\n' +
          '        \'dataframe\': data_df.to_dict(\'records\'), # dataframe的原始表格\n' +
          '        \'sql\': str(ex_sql), # 执行的sql\n' +
          '        \'total_sql\': str(total_sql), # 获取总数的sql\n' +
          '        \'charts\': {\n' +
          '            \'types\': graphicsModel, # 图表格式\n' +
          '            \'data\': ret # 返回的数据格式\n' +
          '        }\n' +
          '    })\n' +
          'return task_run(request, df)',
        js: ''
      },
      serverPackages: [],
      drawer: false,
      dialogVisible: false,
      activeName: 'baseSetting',
      // 模板
      visualTemplate: [],
      // 数据来源
      fromData: {
        table: [],
        filters: {
          fields: [],
          symbol: ['>', '<', '<=', '>=', '=', '!=', 'like', 'not like', 'is null', 'is not null'],
          ret: {}
        },
        valueField: {
          symbol: ['+', '-', '*', '/', '%']
        },
        graphicsModel: [{
          value: 'line',
          label: '折线图',
          icon: 'line'
        }, {
          value: 'bar',
          label: '柱状图',
          icon: 'bar'
        }, {
          value: 'pie',
          label: '扇形图',
          icon: 'pie'
        }, {
          value: 'pivot',
          label: '透视图',
          icon: 'pivot'
        }],
        showMode: [{
          value: 'newVisual',
          label: '新图形'
        }, {
          value: 'append',
          label: '追加'
        }],
        sortBy: [{
          value: 'asc',
          label: '正序'
        }, {
          value: 'desc',
          label: '倒序'
        }],
        trigger: [{
          value: 'item',
          label: '端点'
        }, {
          value: 'axis',
          label: '排列'
        }],
        barShowLabel: [{
          value: true,
          label: '显示'
        }, {
          value: false,
          label: '不显示'
        }]
      },
      rules: {
        templateName: [{ required: true, message: '请填写模板名称', trigger: 'change' }],
        templateMessage: [{ required: true, message: '请填写描述', trigger: 'change' }]
      }
    }
  },
  mounted() {
    // 这里固定商品信息表
    this.fromData.table = [{
      'column': 'shop_info',
      'alias': '商品信息表'
    }]
    /* tableAlias().then((res) => {
      this.fromData.table = res.data
    })*/
    this.loadTemplate()
    this.ScriptTemplateList()
    getServerPackages().then(res => {
      this.serverPackages = res.data
    })
  },
  methods: {
    copyPackagesName() {
      const text = this.serverPackages.toString().replaceAll(',', '')

      const input = document.getElementById('package-content')
      input.value = text
      input.select()
      document.execCommand('copy')
      this.$message({
        type: 'success',
        message: '复制所有包名成功'
      })
    },
    ScriptTemplateList() {

    },
    DeleteScriptTemplate() {

    },
    RunScriptTemplate() {
      runCustomizeScript(this.customizeScript).then(_ => {
        // eslint-disable-next-line no-eval
        eval(this.customizeScript.js)
      })
    },
    SaveScriptTemplate() {

    },
    drawerClose(done) {
      this.$confirm('还有未保存的工作，确定关闭吗？')
        .then(_ => {
          done()
        })
        .catch(_ => {})
    },
    deleteTemplate(id) {
      this.$confirm('此操作将永久删除该模板, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteVisualTemplate({ 'id': id }).then(_ => {
          this.loadTemplate()
          this.$message({
            message: '删除成功',
            type: 'success'
          })
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    loadTemplate() {
      // 加载模板
      getVisualTemplate().then((res) => {
        this.visualTemplate = res.data
      })
    },
    saveTemplate() {
      this.dialogVisible = false
      this.onSubmit(true)
    },
    // 使用模板
    usingTemplate(template) {
      this.filterPayload = template
      // 先选中表
      this.SelectFieldName()
      // 再提交表单
      this.onSubmit()
      // 刷新模板
      this.loadTemplate()
    },
    // 分页修改
    handleSizeChange(lq) {
      this.filterPayload.listQuery.pageSize = lq
      this.filterPayload.listQuery.page = 1
      this.nextData()
    },
    // 修改页码
    handleCurrentChange(lq) {
      this.filterPayload.listQuery.page = lq
      this.onSubmit()
    },
    // 提交和下一页
    onSubmit(isSave = false) {
      this.$emit('getFilter', this.filterPayload, isSave)
    },
    // 删除过滤
    removeShopFilter(item) {
      const index = this.filterPayload.filters.indexOf(item)
      if (index !== -1) {
        this.filterPayload.filters.splice(index, 1)
      }
    },
    addFilter() {
      const fiData = this.fromData.filters.ret
      this.filterPayload.filters.push(fiData)
      this.$set(this.fromData.filters, 'ret', {})
      this.onSubmit()
    },
    delTag(index) {
      this.filterPayload.filters.splice(index, 1)
    },
    selPlat(item) {
      this.filterPayload.platform_id = item
      this.fromData.brand = []
      getBrand({
        platform_id: item
      }).then(res => {
        this.fromData.brand = res.data
      })
    },
    /**
       * 选中表名时
       * @constructor
       */
    SelectFieldName() {
      fieldAlias({
        table_name: this.filterPayload.tableName
      }).then((res) => {
        this.fromData.filters.fields = res.data
      })
    }
  }
}
</script>
<style lang="scss">
.panel-card{
min-height: 91vh;
  max-height: 91vh;
  overflow: auto;
  background-color: white;
  color: black;
}

  .padd-left {
    margin-left: 10px;
  }

  .el-select {
    width: 100%;
  }

  .input-with-select .el-input-group__prepend {
    background-color: #fff;

    .el-select .el-input {
      width: 100px;
    }
  }
</style>
